package com.wys.spring;

import com.wys.spring.controller.servlet.RequestServletProperties;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import springfox.documentation.service.ParameterType;
import springfox.documentation.service.RequestParameter;
import springfox.documentation.spi.DocumentationType;

import java.util.List;
import java.util.Map;

@Getter
@Setter
@ConfigurationProperties(prefix = "wys")
public class SpringCommonProperties {

    /**
     * 对响应数据加密
     */
    @NestedConfigurationProperty
    private ResponseEncrypt responseEncrypt;

    /**
     * 请求配置类
     */
    @NestedConfigurationProperty
    private RequestServletProperties requestServletProperties;


    /**
     * 日志
     */
    @NestedConfigurationProperty
    private Logging logging;

    /**
     * knife4j文档配置
     */
    @NestedConfigurationProperty
    private Swagger swagger;


    /**
     * xxlJob配置
     */
    @NestedConfigurationProperty
    private XXlJobConfig xXlJobConfig;

    @Getter
    @Setter
    public static class Logging {

        /**
         * 开启请求日志 默认开启
         */
        private Boolean requestEnable = true;

        /**
         * 开启响应日志 默认开启
         */
        private Boolean responseEnable = true;

    }

    @Getter
    @Setter
    public static class Swagger {

        /**
         * 添加swagger全局headerName 可以根据','分割多个
         */
        private List<SwaggerRequestParams> requestParameters;

        /**
         * 全局参数类型 如：header、body、param等
         */
        private ParameterType parameterType;

        /**
         * 分组名称
         */
        private String groupName;

        /**
         * 文档类型 swagger2.0 swagger2.1 ...
         */
        private DocType documentationType = DocType.swagger2;

        /**
         * 文档主体内容
         */
        private ApiInfo apiInfo;

        /**
         * 需要在knife4j上排除的字段合集
         */
        private List<SwaggerDynamicParameter> ignoreParameters;

        /**
         * 需要在knife4j上导入的动态字段合集
         */
        private List<SwaggerDynamicParameter> includeParameters;

    }

    @Getter
    @Setter
    public static class SwaggerDynamicParameter {

        /**
         * url路径支持模糊匹配例如:/user/**
         */
        private String path;

        /**
         * 动态值 例如: userName:true 表示展示这个字段,userName:false 表示在当前接口下不展示这个字段
         */
        private Map<String, Boolean> dynamicValue;

    }

    public enum DocType {
        swagger1_2(DocumentationType.SWAGGER_12), swagger2(DocumentationType.SWAGGER_2), swagger3(DocumentationType.OAS_30);

        private DocumentationType documentationType;

        DocType(DocumentationType documentationType) {
            this.documentationType = documentationType;
        }

        public DocumentationType getDocumentationType() {
            return documentationType;
        }
    }

    @Getter
    @Setter
    public static class ApiInfo {

        /**
         * 文档标题
         */
        private String title;
        /**
         * 文档备注
         */
        private String description;

        /**
         * 文档版本
         */
        private String version;
    }

    @Getter
    @Setter
    public static class ResponseEncrypt {

        /**
         * 是否开启api数据服务加密
         */
        private boolean enable;

        /**
         * 加密策略 AES,RSA,3DES
         */
        private EncryptModel encryptModel;

        /**
         * 不需要加密的api路径
         */
        private String excludeUrls;

        public enum EncryptModel {
            RSA, DES, DES3, SHA256
        }

    }

    @Getter
    @Setter
    public static class SwaggerRequestParams {
        private String name;
        private int parameterIndex;
        private ParameterType in;
        private String description;
        private Boolean required;
        private Boolean deprecated;
        private Boolean hidden;
    }


    @Getter
    @Setter
    public static class XXlJobConfig {
        private Boolean enable;
        private String adminAddresses;
        private String accessToken;
        private String appname;
        private String address;
        private String ip;
        private int port;
        private String logPath;
        private int logRetentionDays;

    }

}
